#include "baidu_tts_client.h"
#include <QDebug>
#include <QUrl>
#include <QUrlQuery>
#include <QJsonParseError>
#include <QAudioDeviceInfo>
#include <QDateTime>
#include <QCoreApplication>

const QString BaiduTTSClient::TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
const QString BaiduTTSClient::TTS_URL = "https://tsn.baidu.com/text2audio";

BaiduTTSClient::BaiduTTSClient(QObject *parent)
    : QObject(parent)
    , m_networkManager(nullptr)
    , m_currentReply(nullptr)
    , m_audioOutput(nullptr)
    , m_audioBuffer(nullptr)
    , m_tempAudioFile(nullptr)
    , m_tokenExpireTime(0)
    , m_voice("1")        // 默认普通女声
    , m_speed(5)          // 默认语速
    , m_pitch(5)          // 默认音调
    , m_volume(5)         // 默认音量
    , m_language("zh")    // 默认中文
    , m_initialized(false)
    , m_synthesizing(false)
{
    m_networkManager = new QNetworkAccessManager(this);
    m_audioBuffer = new QBuffer(this);
}

BaiduTTSClient::~BaiduTTSClient()
{
    stopSynthesis();
    if (m_tempAudioFile) {
        delete m_tempAudioFile;
    }
}

bool BaiduTTSClient::initialize(const QString &appId, const QString &apiKey, const QString &secretKey)
{
    if (apiKey.isEmpty() || secretKey.isEmpty()) {
        setLastError("API Key 或 Secret Key 为空");
        return false;
    }

    m_appId = appId;
    m_apiKey = apiKey;
    m_secretKey = secretKey;

    qDebug() << "初始化百度语音合成客户端...";
    qDebug() << "AppID:" << m_appId;
    qDebug() << "API Key:" << (m_apiKey.left(8) + "...");

    // 设置音频输出
    setupAudioOutput();

    // 请求访问令牌
    requestAccessToken();

    return true;
}

void BaiduTTSClient::requestAccessToken()
{
    if (m_currentReply) {
        m_currentReply->abort();
        m_currentReply->deleteLater();
        m_currentReply = nullptr;
    }

    QUrl url(TOKEN_URL);
    QUrlQuery query;
    query.addQueryItem("grant_type", "client_credentials");
    query.addQueryItem("client_id", m_apiKey);
    query.addQueryItem("client_secret", m_secretKey);

    qDebug() << "请求访问令牌:" << url.toString() + "?" + query.toString();

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::UserAgentHeader, "Qt-BaiduTTS/1.0");

    QString postData = query.toString();
    m_currentReply = m_networkManager->post(request, postData.toUtf8());
    connect(m_currentReply, &QNetworkReply::finished, this, &BaiduTTSClient::onTokenReplyFinished);
}

void BaiduTTSClient::onTokenReplyFinished()
{
    if (!m_currentReply) {
        return;
    }

    QNetworkReply *reply = m_currentReply;
    m_currentReply = nullptr;

    if (reply->error() != QNetworkReply::NoError) {
        setLastError(QString("网络请求失败: %1").arg(reply->errorString()));
        reply->deleteLater();
        return;
    }

    QByteArray responseData = reply->readAll();
    reply->deleteLater();

    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData, &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        setLastError(QString("JSON解析失败: %1").arg(parseError.errorString()));
        return;
    }

    QJsonObject jsonObj = jsonDoc.object();

    if (jsonObj.contains("error")) {
        QString error = jsonObj["error"].toString();
        QString errorDesc = jsonObj["error_description"].toString();
        setLastError(QString("获取访问令牌失败: %1 - %2").arg(error, errorDesc));
        return;
    }

    if (jsonObj.contains("access_token")) {
        m_accessToken = jsonObj["access_token"].toString();
        int expiresIn = jsonObj["expires_in"].toInt();
        m_tokenExpireTime = QDateTime::currentSecsSinceEpoch() + expiresIn;

        qDebug() << "成功获取访问令牌，有效期:" << expiresIn << "秒";
        m_initialized = true;
    } else {
        setLastError("响应中没有访问令牌");
    }
}

bool BaiduTTSClient::isTokenValid() const
{
    return !m_accessToken.isEmpty() && 
           QDateTime::currentSecsSinceEpoch() < (m_tokenExpireTime - 60); // 提前60秒刷新
}

bool BaiduTTSClient::synthesizeText(const QString &text)
{
    if (!m_initialized) {
        setLastError("客户端未初始化");
        return false;
    }

    if (text.isEmpty()) {
        setLastError("合成文本为空");
        return false;
    }

    if (m_synthesizing) {
        setLastError("正在进行语音合成");
        return false;
    }

    if (!isTokenValid()) {
        setLastError("访问令牌无效或已过期");
        requestAccessToken();
        return false;
    }

    qDebug() << "开始语音合成:" << text;

    m_synthesizing = true;
    emit synthesisStarted();

    // 构建请求URL和参数
    QUrl url(TTS_URL);
    
    QUrlQuery query;
    query.addQueryItem("tex", text);                    // 要合成的文本
    query.addQueryItem("tok", m_accessToken);           // 访问令牌
    query.addQueryItem("cuid", "qt_baidu_tts_client");  // 用户唯一标识
    query.addQueryItem("ctp", "1");                     // 客户端类型
    query.addQueryItem("lan", m_language);              // 语言
    query.addQueryItem("spd", QString::number(m_speed)); // 语速
    query.addQueryItem("pit", QString::number(m_pitch)); // 音调
    query.addQueryItem("vol", QString::number(m_volume)); // 音量
    query.addQueryItem("per", m_voice);                 // 发音人
    query.addQueryItem("aue", "3");                     // 音频编码(3=mp3)

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::UserAgentHeader, "Qt-BaiduTTS/1.0");

    QString postData = query.toString();
    
    qDebug() << "发送TTS请求到:" << url.toString();
    qDebug() << "请求参数:" << postData;

    if (m_currentReply) {
        m_currentReply->abort();
        m_currentReply->deleteLater();
    }

    m_currentReply = m_networkManager->post(request, postData.toUtf8());
    connect(m_currentReply, &QNetworkReply::finished, this, &BaiduTTSClient::onTTSReplyFinished);

    return true;
}

void BaiduTTSClient::onTTSReplyFinished()
{
    if (!m_currentReply) {
        return;
    }

    QNetworkReply *reply = m_currentReply;
    m_currentReply = nullptr;

    m_synthesizing = false;

    if (reply->error() != QNetworkReply::NoError) {
        setLastError(QString("网络请求失败: %1").arg(reply->errorString()));
        emit synthesisError(m_lastError);
        reply->deleteLater();
        return;
    }

    QByteArray responseData = reply->readAll();
    QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
    
    qDebug() << "收到TTS响应，内容类型:" << contentType << "数据大小:" << responseData.size();

    reply->deleteLater();

    // 检查是否是音频数据
    if (contentType.contains("audio") || 
        (responseData.size() > 1000 && !responseData.startsWith('{'))) {
        // 这是音频数据
        qDebug() << "语音合成成功，音频大小:" << responseData.size() << "字节";
        
        emit audioDataReady(responseData);
        playAudioData(responseData);
        emit synthesisFinished();
    } else {
        // 这可能是错误响应
        QString responseText = QString::fromUtf8(responseData);
        qDebug() << "TTS响应内容:" << responseText;

        // 尝试解析JSON错误
        QJsonParseError parseError;
        QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData, &parseError);
        
        if (parseError.error == QJsonParseError::NoError) {
            QJsonObject jsonObj = jsonDoc.object();
            if (jsonObj.contains("err_msg")) {
                QString errorMsg = jsonObj["err_msg"].toString();
                int errorNo = jsonObj["err_no"].toInt();
                setLastError(QString("语音合成失败[%1]: %2").arg(errorNo).arg(errorMsg));
            } else {
                setLastError("语音合成失败: 未知错误");
            }
        } else {
            setLastError("语音合成失败: 响应格式错误");
        }
        
        emit synthesisError(m_lastError);
    }
}

void BaiduTTSClient::setupAudioOutput()
{
    // 设置音频格式
    QAudioFormat format;
    format.setSampleRate(16000);        // 16kHz采样率
    format.setChannelCount(1);          // 单声道
    format.setSampleSize(16);           // 16位
    format.setCodec("audio/pcm");       // PCM编码
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::SignedInt);

    // 获取默认音频输出设备
    QAudioDeviceInfo outputDevice = QAudioDeviceInfo::defaultOutputDevice();
    
    if (!outputDevice.isFormatSupported(format)) {
        qWarning() << "音频格式不支持，使用最接近的格式";
        format = outputDevice.nearestFormat(format);
    }

    qDebug() << "TTS音频格式:" << format;

    if (m_audioOutput) {
        delete m_audioOutput;
    }

    m_audioOutput = new QAudioOutput(outputDevice, format, this);
    connect(m_audioOutput, &QAudioOutput::stateChanged, 
            this, &BaiduTTSClient::onAudioOutputStateChanged);
}

void BaiduTTSClient::playAudioData(const QByteArray &audioData)
{
    if (!m_audioOutput || audioData.isEmpty()) {
        return;
    }

    // 将音频数据写入临时文件
    if (m_tempAudioFile) {
        delete m_tempAudioFile;
    }

    m_tempAudioFile = new QTemporaryFile(this);
    m_tempAudioFile->setFileTemplate(QCoreApplication::applicationDirPath() + "/tts_XXXXXX.mp3");
    
    if (m_tempAudioFile->open()) {
        m_tempAudioFile->write(audioData);
        m_tempAudioFile->close();
        
        qDebug() << "音频文件保存到:" << m_tempAudioFile->fileName();
        
        // 使用系统播放器播放MP3文件
        QString fileName = m_tempAudioFile->fileName();
        QProcess *playProcess = new QProcess(this);
        
        connect(playProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                [this, playProcess](int exitCode, QProcess::ExitStatus exitStatus) {
                    Q_UNUSED(exitCode)
                    Q_UNUSED(exitStatus)
                    qDebug() << "音频播放完成";
                    playProcess->deleteLater();
                    emit synthesisFinished();
                });

        // 尝试不同的音频播放器
        QStringList players = {"mpv", "mplayer", "vlc", "paplay"};
        QString player;
        
        for (const QString &p : players) {
            if (QProcess::execute("which", QStringList() << p) == 0) {
                player = p;
                break;
            }
        }

        if (!player.isEmpty()) {
            qDebug() << "使用" << player << "播放音频:" << fileName;
            playProcess->start(player, QStringList() << fileName);
        } else {
            qWarning() << "没有找到可用的音频播放器";
            playProcess->deleteLater();
        }
    }
}

void BaiduTTSClient::onAudioOutputStateChanged(QAudio::State state)
{
    qDebug() << "音频输出状态变化:" << state;
    
    if (state == QAudio::IdleState) {
        m_audioOutput->stop();
        emit synthesisFinished();
    }
}

void BaiduTTSClient::stopSynthesis()
{
    if (m_currentReply) {
        m_currentReply->abort();
        m_currentReply->deleteLater();
        m_currentReply = nullptr;
    }

    if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
        m_audioOutput->stop();
    }

    m_synthesizing = false;
}

QString BaiduTTSClient::urlEncode(const QString &text)
{
    return QUrl::toPercentEncoding(text);
}

void BaiduTTSClient::setLastError(const QString &error)
{
    m_lastError = error;
    qWarning() << "百度TTS错误:" << error;
} 